//
//  ICENavigatorAction.m
//  ICEubLib
//
//  Created by wujianrong on 16/4/17.
//  Copyright © 2016年 wanda. All rights reserved.
//

#import "ICENavigatorAction.h"
#import "ICENavigatorSub.h"
#import <objc/message.h>
#import "ICECore.h"
#import "NSArray+IceNavigator.h"
#import "UINavigationController+IceNavigator.h"
#import "NSDictionary+iceNavigator.h"
#import "NSURL+iceNavigator.h"
#import "ICENavigatorProtocol.h"

static ICENavigatorAction * _ICENavigator = nil;
static UINavigationController* _ICENavigationController = nil;

static NSMutableArray* _ICEUrlSchemeArray = nil;
static NSMutableArray* _ICETopLevelVcs = nil;
static NSMutableArray* _ICETopLevelExcetpionVcs = nil;

//scheme dict
static NSMutableDictionary* _ICEUrlMapDictionary = nil;
static NSMutableDictionary* _ICEOutSideUrlMapDictionary = nil;

@implementation ICENavigatorAction

+ (void)initialize {
    _ICENavigator = [[self alloc] init];
    _ICEUrlMapDictionary = [[NSMutableDictionary alloc]init];
    _ICEOutSideUrlMapDictionary = [[NSMutableDictionary alloc]init];
    _ICEUrlSchemeArray = [[NSMutableArray alloc]init];
    _ICETopLevelVcs = [[NSMutableArray alloc]init];
    _ICETopLevelExcetpionVcs = [[NSMutableArray alloc]init];
    [_ICEUrlSchemeArray addObject:@"ICE"];//默认添加一个，方便内部开发
}

+(void)openViewController:(UIViewController*)vc params:(NSDictionary*)params
{
    if ([[vc class] respondsToSelector:@selector(isEnablePublicParams)]) {
        BOOL isEnablePublicParams = [[vc class] isEnablePublicParams];
        if (isEnablePublicParams) {
            [(id<ICENavigatorProtocol>)vc setPublicParams:params];
        }
    }

    if ([vc respondsToSelector:@selector(handleWillOpenUrlWithParams:)]) {
        if ([(id<ICENavigatorProtocol>)vc handleWillOpenUrlWithParams:params] == NO) {
            //如果响应对象实现handleWillOpenUrlWithParams方法 并且 handleWillOpenUrlWithParams 方法返回了NO, 则终止后续行为
            return;
        }
    }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
    if ([vc respondsToSelector:@selector(universal_handleUrlScheme)]) {//处理通用功能，可以是脱离页面的scheme跳转
        ((void(*)(id, SEL))objc_msgSend)(vc, @selector(universal_handleUrlScheme));
        return;
    }
#pragma clang diagnostic pop
    
    BOOL isSingleton = NO;
    if ([[vc class] respondsToSelector:@selector(isSingleton)]) {
        isSingleton = [[vc class] isSingleton];
    }
    
    if (YES == isSingleton) {
        [self pushSingleViewController:vc];
    }
    else
    {
        [self pushViewController:vc];
    }
    
}

+(void)pushSingleViewController:(UIViewController*)vc
{
    
    NSMutableArray *controllers = [NSMutableArray arrayWithArray:_ICENavigationController.viewControllers];
    if ([controllers iceNavigatorFind:^BOOL(UIViewController *obj) {
        return (obj == vc);
    }]) {
        if (vc != [controllers lastObject]) {
            UIViewController* topVc = [_ICENavigationController topViewController];
            if ([[topVc class] respondsToSelector:@selector(shouldDimiss)]) {
                if ([[topVc class] shouldDimiss] == YES) {
                    [_ICENavigationController ICEDismissToViewController:vc];
                    return;
                }
            }
            [_ICENavigationController popToViewController:vc animated:YES];
        }
        else {
            [vc viewWillAppear:NO];
            [vc viewDidAppear:NO];
        }
    } else {
        [self pushViewController:vc];
    }
}

+ (void)pushViewController:(UIViewController *)controller{
    if ([[controller class] respondsToSelector:@selector(shouldPresent)]) {
        if ([[controller class] shouldPresent] == YES ) {
            [_ICENavigationController ICEPresentViewController:controller];
            return;
        }
    }
    [_ICENavigationController pushViewController:controller animated:YES];
}

+ (UIViewController *)obtainControllerWithClassName:(NSString *)viewControllerClassName {
    if (viewControllerClassName == nil) return nil;
    Class class = NSClassFromString(viewControllerClassName);
    if ([class respondsToSelector:@selector(isSingleton)] && [class performSelector:@selector(isSingleton)]) {
        UIViewController *controller = [[_ICENavigationController viewControllers] iceNavigatorFind:^BOOL(UIViewController *controller) {
            return [controller isKindOfClass:class];
        }];
        return controller ?: [class new];
    }
    return [class new];
}

+(NSURL*)checkAndGetStandardUrlWithUrl:(id)urlString
{
    if ([urlString isKindOfClass:[NSURL class]]) {
        return urlString;
    }
    
    NSString* tempString = nil;
    if ([urlString isKindOfClass:[NSString class]]) {
        tempString = urlString;
    }
    

    if (ICESafeString(tempString).length < 1) {
        return nil;
    }
    
    NSURL* url = [NSURL URLWithString:tempString];
    return url;
}

+(NSString*)checkAndGetViewControllerNameWithUrl:(id)urlString
{
    NSURL* url = [self checkAndGetStandardUrlWithUrl:urlString];
    if (url == nil) {
        return nil;
    }
    //查看scheme是否注册过
    id schemeObj = [_ICEUrlSchemeArray iceNavigatorFind:^BOOL(id obj) {
        if ([[obj lowercaseString] isEqualToString:[[url scheme]lowercaseString]] == YES) {
            return YES;
        }
        return  NO;
    }];
    if (schemeObj == nil) {
        return nil;
    }
    
    //寻找注册表中是否含有该host
    id hostObj = [_ICEUrlMapDictionary iceNavigatorFindKey:^BOOL(id obj) {
        if ([[obj lowercaseString] isEqualToString:[[url host]lowercaseString]] == YES) {
            return YES;
        }
        return  NO;
    }];
    
    if (hostObj == nil) {
        return nil;
    }
    
    //生成页面
    NSString* value = [_ICEUrlMapDictionary objectForKey:hostObj];
    return value;
}

+(UIViewController*)checkAndGetViewcontrollerWithUrl:(id)urlString
{
    NSString* className = [self checkAndGetViewControllerNameWithUrl:urlString];
    if (ICESafeString(className).length <= 0) {
        return nil;
    }
    UIViewController* vc = [self obtainControllerWithClassName:className];
    if (vc == nil) {
        return nil;
    }
    return vc;
}

+(NSString*)checkRelyingOnViewControllerWithUrl:(id)urlString
{
    NSString* className = [self checkAndGetViewControllerNameWithUrl:urlString];
    if (ICESafeString(className).length <= 0) {
        return nil;
    }
    
    NSURL* url = [self checkAndGetStandardUrlWithUrl:urlString];
    NSDictionary* params = [url iceNavigatorParseQuery];
    Class class = NSClassFromString(className);
    if (class) {
        if ([class respondsToSelector:@selector(relyingOnOtherUrlSchemeWithParams:)]) {
            NSString* relyingUrl = [class performSelector:@selector(relyingOnOtherUrlSchemeWithParams:) withObject:params];
            return relyingUrl;
        }
    }
    
    return nil;
}

#pragma mark - public methods


+(BOOL)isCurrentVcTopLevelWithFromViewController:(UIViewController*)fromVc
{
    UIViewController* topVc = [ICE_ROOT_NAVIGATION_CONTROLLER topViewController];
    for (NSString* className in _ICETopLevelVcs) {
        if ([topVc class] == NSClassFromString(className)) {
            if ([fromVc class] == NSClassFromString(className)) {
                return NO;
            }
            return YES;
        }
    }
    
    return NO;
}

+(BOOL)isCurrentVcTopLevelWithFromViewController:(UIViewController*)fromVc url:(NSString*)urlString
{
    
    NSString* className = [self checkAndGetViewControllerNameWithUrl:urlString];
    if (ICESafeString(className).length > 0) {
        id vc = [_ICETopLevelExcetpionVcs iceNavigatorFind:^BOOL(id obj) {
            if ([[obj lowercaseString] isEqualToString:[className lowercaseString]] == YES) {
                return YES;
            }
            return  NO;
        }];
        if (vc != nil) {
            return NO;
        }
    }
    
   
    
    UIViewController* topVc = [ICE_ROOT_NAVIGATION_CONTROLLER topViewController];
    for (NSString* className in _ICETopLevelVcs) {
        if ([topVc class] == NSClassFromString(className)) {
            if ([fromVc class] == NSClassFromString(className)) {
                return NO;
            }
            return YES;
        }
    }
    
    
    return NO;
}

+(UIViewController *)openURLString:(id)urlString fromViewController:(UIViewController *)controller initAfterAlloc:(iceNavigatorInitAfterViewControllerAlloc)block
{
    UIViewController* vc = [self checkAndGetViewcontrollerWithUrl:[urlString copy]];
    if (vc == nil) {
        return nil;
    }
    
    NSURL* url = [self checkAndGetStandardUrlWithUrl:urlString];
    if (url == nil) {
        return nil;
    }
    NSMutableDictionary *dic = [[NSMutableDictionary alloc]initWithDictionary:[url iceNavigatorParseQuery]];
    if (block) {
        NSDictionary* tempDit = block(vc);
       // WDAssert([tempDit isKindOfClass:[NSDictionary class]], @"不是NSDictionary类型");
        if ([tempDit isKindOfClass:[NSDictionary class]]) {
            [dic addEntriesFromDictionary:tempDit];
        }
    }
    
    //打开页面
    [self openViewController:vc params:dic];
    return vc;
}

+(UIViewController *)openURLString:(id)urlString fromViewController:(UIViewController *)controller
{
    UIViewController* vc = [self checkAndGetViewcontrollerWithUrl:[urlString copy]];
    if (vc == nil) {
        return nil;
    }
    
    NSURL* url = [self checkAndGetStandardUrlWithUrl:urlString];
    if (url == nil) {
        return nil;
    }
    NSDictionary *dic = [url iceNavigatorParseQuery];
    
    //打开页面
    [self openViewController:vc params:dic];
    return vc;
}

+(void)loadWithRootNavigationController:(UINavigationController *)navigationController schemeArray:(NSArray *)schemeArray urlMappingDictionary:(NSDictionary *)urlMappingDictionary outsideUrlMappingDictionary:(NSDictionary *)outsideUrlMappingDictionary
{
    if (navigationController == nil) {
        return;
    }
    _ICENavigationController = navigationController;
    [_ICEUrlSchemeArray addObjectsFromArray:[schemeArray copy]];
    [_ICEUrlMapDictionary addEntriesFromDictionary:[urlMappingDictionary copy]];
    [_ICEUrlMapDictionary addEntriesFromDictionary:[outsideUrlMappingDictionary copy]];
    [_ICEOutSideUrlMapDictionary addEntriesFromDictionary:[outsideUrlMappingDictionary copy]];
    //todo 检测是否有该vc
}

+(void)setTopLevelViewControllers:(NSArray *)topLevelVCs
{
    if (topLevelVCs.count <= 0) {
        return;
    }
    [_ICETopLevelVcs addObjectsFromArray:topLevelVCs];
}

+(void)setTopLevelViewControllers:(NSArray *)topLevelVCs exceptionViewControllers:(NSArray *)exceptionVCs
{
    if (topLevelVCs.count <= 0) {
        return;
    }
    [_ICETopLevelVcs addObjectsFromArray:topLevelVCs];
    
    if (exceptionVCs.count <= 0) {
        return;
    }
    [_ICETopLevelExcetpionVcs addObjectsFromArray:exceptionVCs];
}

+(UINavigationController*)getRootNavigationViewController
{
    return _ICENavigationController;
}

+(void)addScheme:(NSString*)scheme
{
    [_ICEUrlSchemeArray addObject:[scheme copy]];
}

+(void)addUrlMap:(NSDictionary*)urlMappingDictionary
{
    [_ICEUrlMapDictionary addEntriesFromDictionary:[urlMappingDictionary copy]];
}

+(NSArray*)getSchemeArray
{
    return [_ICEUrlSchemeArray copy];
}

+(NSString*)getPreviousViewContrllerFromStack
{
    if ([_ICENavigationController viewControllers].count <= 1) {
        return nil;
    }
    UIViewController* vc = [[_ICENavigationController viewControllers] objectAtIndex:([_ICENavigationController viewControllers].count-2)];
    return NSStringFromClass([vc class]);
}

+(BOOL)canOpenUrl:(NSString*)url inMapDict:(NSDictionary*)dict
{
    if (ICESafeString(url).length < 4) {
        return NO;
    }
    NSURL* uu = [NSURL URLWithString:ICESafeString(url)];
    NSString* key = [dict iceNavigatorFindKey:^BOOL(id obj) {
        if ([[obj lowercaseString] isEqualToString:[[uu host] lowercaseString]]) {
            return YES;
        }
        return NO;
    }];
    if (key.length > 0) {
        return YES;
    }
    return NO;
}

+ (BOOL)canOpenOutSideWithUrlScheme:(NSString*)url
{
    return [self canOpenUrl:url inMapDict:_ICEOutSideUrlMapDictionary];
}

+ (BOOL)canOpenUrlScheme:(NSString*)url
{
    return [self canOpenUrl:url inMapDict:_ICEUrlMapDictionary];
}

@end
